package com.xinyi.basic.base.adapter

import android.content.Context
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import androidx.annotation.IdRes
import androidx.core.util.forEach
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

/**
 * @author 新一
 * @date 2023/3/28 16:30
 * @description 适配器基类
 */
abstract class BaseAdapter<T> : RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private var mListBeans: MutableList<T> = mutableListOf()

    /** 上下文对象  */
    private var mContext: Context? = null

    /** RecyclerView 对象  */
    private var mRecyclerView: RecyclerView? = null

    /** 条目点击监听器  */
    private var mItemClickListener: OnItemClickListener? = null

    /** 条目长按监听器  */
    private var mItemLongClickListener: OnItemLongClickListener? = null

    /** 条目子 View 点击监听器  */
    private var mChildClickListeners: SparseArray<OnChildClickListener?>? = null

    /** 条目子 View 长按监听器  */
    private var mChildLongClickListeners: SparseArray<OnChildLongClickListener?>? = null

    constructor(mContext: Context?): super() {
        this.mContext = mContext
    }

    constructor(mListBeans: MutableList<T>, mContext: Context?) {
        this.mListBeans = mListBeans
        this.mContext = mContext
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return onCreateView(parent, viewType)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        onBindViewClickListener(holder, position)
    }

    override fun getItemCount(): Int {
        return if (mListBeans.size > 0) mListBeans.size else 0
    }

    fun getItem(position: Int): T? {
        if (position >= 0 && position < mListBeans.size) {
            return mListBeans[position]
        }
        return null
    }

    protected abstract fun onCreateView(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder

    private fun onBindViewClickListener(holder: RecyclerView.ViewHolder, position: Int) {
        mItemClickListener?.let { listener ->
            holder.itemView.setOnClickListener {
                listener.onItemClick(mRecyclerView, holder.itemView, position)
            }
        }
        mItemLongClickListener?.let { listener ->
            holder.itemView.setOnLongClickListener {
                listener.onItemLongClick(mRecyclerView, holder.itemView, position)
            }
        }
        mChildClickListeners?.let { listener ->
            listener.forEach { key, value ->
                value?.let {
                    val childView = holder.itemView.findViewById<View>(key)
                    childView?.setOnClickListener { v ->
                        value.onChildClick(mRecyclerView, v, position)
                    }
                }
            }
        }
        mChildLongClickListeners?.let { listener ->
            listener.forEach { key, value ->
                value?.let {
                    val childView = holder.itemView.findViewById<View>(key)
                    childView?.setOnLongClickListener { v ->
                        value.onChildLongClick(mRecyclerView, v, position)
                    }
                }
            }
        }
        onBindView(holder, position)
    }

    /**
     * 数据绑定回调
     * @param holder 条目
     * @param position 下标
     */
    protected abstract fun onBindView(holder: RecyclerView.ViewHolder?, position: Int)

    /**
     * @return 获取列表所有数据
     */
    fun getListBeans(): List<T> {
        return mListBeans
    }

    /**
     * @param mList 添加一个集合
     */
    fun setListBeans(mList: MutableList<T>) {
        mListBeans = mList
    }

    /**
     * 添加一条数据
     */
    fun appendBean(bean: T) {
        mListBeans.add(bean)
    }

    /**
     * @param bean 插入一条数据到第一个
     */
    fun appendFirstBean(bean: T) {
        mListBeans.add(0, bean)
    }

    /**
     * @param mList 添加一个集合 默认添加到后面
     */
    fun appendList(mList: MutableList<T>) {
        appendCollection(mList, false)
    }

    /**
     * @param mList 添加一个集合 默认插入到前面
     */
    fun appendListByFirstElement(mList: MutableList<T>) {
        appendCollection(mList, true)
    }

    /**
     * @param mList 添加一个集合
     * @param first true：插入最前面，false：添加到后面
     */
    private fun appendCollection(mList: MutableList<T>, first: Boolean) {
        if (first) {
            mListBeans.addAll(0, mList)
        } else {
            mListBeans.addAll(mList)
        }
    }

    /**
     * 清空所有数据
     */
    fun clear() {
        mListBeans.clear()
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        mRecyclerView = recyclerView
        // 判断当前的布局管理器是否为空，如果为空则设置默认的布局管理器
        if (mRecyclerView?.layoutManager == null) {
            val layoutManager = generateDefaultLayoutManager(mContext)
            if (layoutManager != null) {
                mRecyclerView?.layoutManager = layoutManager
            }
        }
    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
        mRecyclerView = null
    }

    /**
     * 生成默认的布局摆放器
     */
    open fun generateDefaultLayoutManager(context: Context?): RecyclerView.LayoutManager? {
        return LinearLayoutManager(context)
    }

    /**
     * 设置 RecyclerView 条目点击监听
     */
    fun setOnItemClickListener(listener: OnItemClickListener?) {
        mItemClickListener = listener
    }

    /**
     * 设置 RecyclerView 条目子 View 点击监听
     */
    fun setOnChildClickListener(@IdRes id: Int, listener: OnChildClickListener?) {
        if (mChildClickListeners == null) {
            mChildClickListeners = SparseArray()
        }
        mChildClickListeners?.put(id, listener)
    }

    /**
     * 设置 RecyclerView 条目长按监听
     */
    fun setOnItemLongClickListener(listener: OnItemLongClickListener?) {
        mItemLongClickListener = listener
    }

    /**
     * 设置 RecyclerView 条目子 View 长按监听
     */
    fun setOnChildLongClickListener(@IdRes id: Int, listener: OnChildLongClickListener?) {
        if (mChildLongClickListeners == null) {
            mChildLongClickListeners = SparseArray()
        }
        mChildLongClickListeners?.put(id, listener)
    }

    /**
     * RecyclerView 条目点击监听类
     */
    interface OnItemClickListener {
        /**
         * 当 RecyclerView 某个条目被点击时回调
         *
         * @param recyclerView      RecyclerView 对象
         * @param itemView          被点击的条目对象
         * @param position          被点击的条目位置
         */
        fun onItemClick(recyclerView: RecyclerView?, itemView: View?, position: Int)
    }

    /**
     * RecyclerView 条目长按监听类
     */
    interface OnItemLongClickListener {
        /**
         * 当 RecyclerView 某个条目被长按时回调
         *
         * @param recyclerView      RecyclerView 对象
         * @param itemView          被点击的条目对象
         * @param position          被点击的条目位置
         * @return                  是否拦截事件
         */
        fun onItemLongClick(recyclerView: RecyclerView?, itemView: View?, position: Int): Boolean
    }

    /**
     * RecyclerView 条目子 View 点击监听类
     */
    interface OnChildClickListener {
        /**
         * 当 RecyclerView 某个条目 子 View 被点击时回调
         *
         * @param recyclerView      RecyclerView 对象
         * @param childView         被点击的条目子 View
         * @param position          被点击的条目位置
         */
        fun onChildClick(recyclerView: RecyclerView?, childView: View?, position: Int)
    }

    /**
     * RecyclerView 条目子 View 长按监听类
     */
    interface OnChildLongClickListener {
        /**
         * 当 RecyclerView 某个条目子 View 被长按时回调
         *
         * @param recyclerView      RecyclerView 对象
         * @param childView         被点击的条目子 View
         * @param position          被点击的条目位置
         */
        fun onChildLongClick(recyclerView: RecyclerView?, childView: View?, position: Int): Boolean
    }
}